package com.jml.spring.factory;

import com.jml.spring.model.BeanDefinition;
import com.jml.spring.model.PropertyValue;
import com.jml.spring.resolver.BeanDefinitionValueResolver;
import com.jml.spring.utils.ReflectUtils;

import java.util.List;

/**
 * 完成Bean的创建和依赖注入
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

    @Override
    protected Object createBean(BeanDefinition bd) {
        // 2.3.2.1.1 Bean的实例化（new对象）
        Object bean = createBeanInstance(bd);
        // 2.3.2.1.2 Bean的依赖注入（setter方法）
        populateBean(bean,bd);
        // 2.3.2.1.3 Bean的初始化（调用初始化方法，比如AOP代理对象的产生流程）
        initializeBean(bean,bd);
        return bean;
    }

    private void initializeBean(Object bean, BeanDefinition bd) {
        // TODO Aware接口的处理
        // TODO InitializingBean接口的afterPropertiesSet方法的调用
        // init-method标签属性对应的初始化方法的调用
        invokeInitMethod(bean,bd);
        // TODO AOP产生代理对象流程的入口
    }

    private void invokeInitMethod(Object bean, BeanDefinition bd) {
        String initMethod = bd.getInitMethod();
        if (initMethod == null || initMethod.equals("")){
            return;
        }

        ReflectUtils.invokeMethod(bean,initMethod);
    }


    private void populateBean(Object bean, BeanDefinition bd) {
        List<PropertyValue> pvs = bd.getPropertyValues();
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this);
        for (PropertyValue pv : pvs) {
            String name = pv.getName();
            Object value = pv.getValue();
            // 得到，真正要依赖注入的值
            Object valueToUse = valueResolver.resoleValue(value);
            //反射赋值
            ReflectUtils.setProperty(bean,name,valueToUse);
        }
    }


    private Object createBeanInstance(BeanDefinition bd) {
        // TODO 静态工厂创建
        // TODO 实例工厂创建
        // 构造器创建
        Object bean = ReflectUtils.newInstance(bd.getClazzType());
        return bean;
    }

}
